'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');
const fs = require('fs');
const path = require('path');
const prompts = require('./prompt');
const utils = require('./utils');

module.exports = class extends Generator {
  constructor(args, opts) {
    super(args, opts);

    this.option('skip-welcome-message', {
      desc: 'skip yeoman welcome message!',
      type: Boolean,
      default: false
    });

    this.option('skip-install', {
      desc: 'skip package dependent installation!',
      type: Boolean,
      default: false
    });
  }

  initializing() {
    if (!this.options['skip-welcome-message']) {
      this.log(yosay(`开始运行 ${chalk.greenBright('generator-send-react')} 构建React项目`));
    }
  }

  async prompting() {
    const answer = await this.prompt(prompts);
    if (answer.appName !== utils.yeoman.getAppName()) {
      answer.appName = utils.yeoman.getAppName(answer.appName);
    }
    this.appName = answer.appName;
    this.version = answer.version;
    this.description = answer.description;
    this.entryPoint = answer.entryPoint;
    this.author = answer.author;
    this.email = answer.email;
    this.repository = answer.repository;
    this.pkgman = answer.pkgman;
    this.state = answer.state;
    this.license = answer.license;
  }

  configuring() {
    // 读取状态管理对应的 package.json 配置
    let defpkgSettings = this.fs.readJSON(this.templatePath(`../packages/${this.state}.package.json`));
    const defReadmePath = this.templatePath(`../README/${this.state}.readme.md`);
    defpkgSettings = Object.assign(
      {
        name: this.appName,
        private: true,
        version: this.version,
        description: this.description,
        main: this.entryPoint,
        author: this.author,
        email: this.email,
        repository: this.repository,
        license: this.license
      },
      defpkgSettings
    );
    this.fs.extendJSON(this.destinationPath('package.json'), defpkgSettings);
    this.fs.copyTpl(defReadmePath, this.destinationPath('README.md'), {
      appName: this.appName,
      pkgman: this.pkgman
    });
  }

  writing() {
    this._copyTemplateFiles(this.sourceRoot());
    this._copyTemplateFiles(this.templatePath(`../states/${this.state}`));
    this.fs.copyTpl(this.templatePath(`../LICENSES/${this.license}`), this.destinationPath('LICENSE'), {
      date: new Date().getFullYear(),
      author: this.author,
      email: this.email
    });
  }

  install() {
    this.installDependencies({
      bower: false,
      npm: this.pkgman === 'npm',
      yarn: this.pkgman === 'yarn'
    });
  }

  end() {
    this.log(chalk.blue('project construction completed!'));
    this.log(chalk.blue(`start running: ${this.pkgman} run start.`));
    this.log(chalk.blue(`build project: ${this.pkgman} run build.`));
  }

  /**
   * @description 复制模板文件
   * @param {string} dirpath templates文件路径
   */
  _copyTemplateFiles(dirpath) {
    const replaceReg = /.*(templates|mobx|default|redux)(\\|\/)/gi;
    const copyFiles = dirname => {
      const files = fs.readdirSync(dirname);
      files.forEach(file => {
        const filepath = path.join(dirname, file);
        const stat = fs.statSync(filepath);
        if (stat.isDirectory()) {
          copyFiles(filepath);
        } else {
          this.fs.copy(
            this.templatePath(filepath),
            this.destinationPath(filepath.replace(replaceReg, ''))
          );
        }
      });
    };
    copyFiles(dirpath);
  }
};
